package com.itheima.blog.admin.service.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.itheima.api.client.dto.TBannerDto;
import com.itheima.blog.admin.entity.TBanner;
import com.itheima.blog.admin.dao.TBannerMapper;
import com.itheima.blog.admin.service.ITBannerService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itheima.blog.util.UserThreadLocalUtils;
import com.itheima.blog.admin.config.MinioConfig;
import com.itheima.common.domain.PageReqDto;
import com.itheima.common.domain.PageResDto;
import com.itheima.common.domain.R;
import com.itheima.common.exception.BadRequestException;
import com.itheima.common.utills.BeanUtils;
import io.minio.*;
import io.minio.messages.DeleteObject;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;

/**
 * <p>
 * 轮播图设置表 服务实现类
 * </p>
 *
 * @author blog
 * @since 2023-07-11
 */
@Service
@RequiredArgsConstructor
public class TBannerServiceImpl extends ServiceImpl<TBannerMapper, TBanner> implements ITBannerService {

    private final MinioConfig minioConfig;
    private final TBannerMapper bannerMapper;

    @Override
    public PageResDto<TBannerDto> findPage(PageReqDto pageReqDto) {
        //获取分页条件
        Integer page = pageReqDto.getPage();
        Integer size = pageReqDto.getSize();
        int i = (page - 1) * size;
        //获取分页数据
        Page<TBanner> bannerPage = lambdaQuery().orderByDesc(TBanner::getCreateTime)
                .page(new Page<>(i, size));

        List<TBanner> records = bannerPage.getRecords();
        List<TBannerDto> tBannerDtos = BeanUtils.copyList(records, TBannerDto.class);
        return new PageResDto<>(pageReqDto,bannerPage.getTotal(), tBannerDtos);
    }

    @Override
    public R<TBanner> findBannerById(Long id) {
        //根据id查询轮播图
        TBanner tBanner = lambdaQuery().eq(TBanner::getId, id).one();
        //封装返回
        return R.ok(tBanner);
    }

    @Override
    public void uploadBannerPicture(MultipartFile file){
        InputStream inputStream = null;
        //创建Minio的连接对象
        MinioClient minioClient = getMinioClient();
        String bucketName = minioConfig.getBucket();
        try {
            inputStream = file.getInputStream();
            //基于官网的内容，判断文件存储的桶是否存在 如果桶不存在就创建桶
            boolean b = minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
            if (!b) {
                minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
            }
            String fileName = file.getOriginalFilename();
            if (fileName==null)
                throw new BadRequestException("文件名为null");
            //时间+UUID+文件后缀
            String objectName = new SimpleDateFormat("yyyy/MM/dd/").format(new Date()) + UUID.randomUUID().toString().replaceAll("-", "") + fileName.substring(fileName.lastIndexOf("."));
            //上传轮播图到minio
            minioClient.putObject(PutObjectArgs.builder()
                    .object(objectName)
                    .bucket(bucketName)
                    .contentType(file.getContentType())
                    .stream(inputStream, file.getSize(),-1).build());
            String url = minioConfig.getUrl() + "/" + minioConfig.getBucket() + "/" + objectName;
            TBanner tBanner = new TBanner();
            Integer adminUserId = UserThreadLocalUtils.getAdminUserId();
            //绑定用户id
            //tBanner.setUserId(adminUserId);
            tBanner.setUrl(url);
            tBanner.setCreateTime(LocalDateTime.now());
            save(tBanner);
        }catch(Exception e){
            e.printStackTrace();
        }finally {
            //防止内存泄漏
            if (inputStream != null) {
                try {
                    inputStream.close(); // 关闭流
                } catch (IOException e) {
                    log.debug("inputStream close IOException:" + e.getMessage());
                }
            }
        }

    }

    private String uploadMinio(MultipartFile file) {
        InputStream inputStream = null;
        //创建Minio的连接对象
        MinioClient minioClient = getMinioClient();
        String bucketName = minioConfig.getBucket();
        try {
            inputStream = file.getInputStream();
            //基于官网的内容，判断文件存储的桶是否存在 如果桶不存在就创建桶
            boolean b = minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
            if (!b) {
                minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
            }
            String fileName = file.getOriginalFilename();
            if (fileName==null)
                throw new BadRequestException("文件名为null");
            //时间+UUID+文件后缀
            String objectName = new SimpleDateFormat("yyyy/MM/dd/").format(new Date()) + UUID.randomUUID().toString().replaceAll("-", "") + fileName.substring(fileName.lastIndexOf("."));
            //上传轮播图到minio
            minioClient.putObject(PutObjectArgs.builder()
                    .object(objectName)
                    .bucket(bucketName)
                    .contentType(file.getContentType())
                    .stream(file.getInputStream(), file.getSize(),-1).build());
            return minioConfig.getUrl() + "/" + minioConfig.getBucket() + "/" + objectName;
        }catch(Exception e){
            e.printStackTrace();
            return "错误";
        }finally {
            //防止内存泄漏
            if (inputStream != null) {
                try {
                    inputStream.close(); // 关闭流
                } catch (IOException e) {
                    log.debug("inputStream close IOException:" + e.getMessage());
                }
            }
        }
    }

    @Override
    public void deleteBannerById(List<Long> ids) {
        if (ids==null)
            throw new BadRequestException("请求参数不能为空");
        List<TBanner> tBannerList = bannerMapper.selectBatchIds(ids);
        //处理url，获得文件名
        List<DeleteObject> deleteObjects = new ArrayList<>(tBannerList.size());
        for (TBanner tBanner : tBannerList) {
            String url = tBanner.getUrl();
            int i = url.lastIndexOf("/");
            String s = url.substring(i+1);
            deleteObjects.add(new DeleteObject(s));
        }

        //获取MinioClient连接
        MinioClient minioClient = getMinioClient();
        minioClient.removeObjects(RemoveObjectsArgs.builder()
                .bucket(minioConfig.getBucket())
                .objects(deleteObjects)
                .build());

        removeBatchByIds(ids);
    }

    @Override
    public void updateBannerPicture(MultipartFile file, Long id) {
        TBanner banner = lambdaQuery().eq(TBanner::getId, id).one();
        //处理url，获得文件名
        List<DeleteObject> deleteObjects = new ArrayList<>();
            String url = banner.getUrl();
            int i = url.lastIndexOf("/");
            String s = url.substring(i+1);
            deleteObjects.add(new DeleteObject(s));

        //获取MinioClient连接
        MinioClient minioClient = getMinioClient();
        minioClient.removeObjects(RemoveObjectsArgs.builder()
                .bucket(minioConfig.getBucket())
                .objects(deleteObjects)
                .build());
        String uploadMinio = uploadMinio(file);
        TBanner tBanner = new TBanner();
        tBanner.setUpdateTime(LocalDateTime.now());
        tBanner.setUrl(uploadMinio);
        tBanner.setId(id);
        updateById(tBanner);
    }


    /**
     * 获取操作对象Minio连接的方法
     * 获取Minio连接
     * @return
     */
    public MinioClient getMinioClient() {
        return MinioClient.builder()
                .endpoint(minioConfig.getUrl())
                .credentials(minioConfig.getAccessKey(), minioConfig.getSecretKey())
                .build();
    }

}
